package com.mycat.redis.util;

import com.mycat.redis.pool.JedisConnection;
import com.mycat.redis.pool.single.RedisSinglePool;
import redis.clients.jedis.Jedis;

import java.util.List;

/**
 * Redis工具类
 *
 * @author roger.
 * @email 190642964@qq.com
 * @create 2016-12-20
 */
public class JedisUtil {

    private static JedisConnection getInstance() {
        return RedisSinglePool.getInstance();
    }

    /**********************************************
     * connection
     *********************************************/
    public static class JedisConnectionUtil {
        /**
         * 验证客户端和服务端是否正常连接
         *
         * @return 正常-PONG，否则返回一个连接错误
         */
        public static String ping() {
            Jedis jedis = getInstance().getResource();
            String data = jedis.ping();
            jedis.close();
            return data;
        }

        /**
         * 键的重命名，不存在旧的key时出现异常
         *
         * @param oldKey 旧的键
         * @param newKey 新的键
         * @return 成功-OK
         */
        public static String rename(String oldKey, String newKey) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.rename(oldKey, newKey);
            jedis.close();
            return data;
        }

        /**
         * 清空当前数据库下所有数据
         *
         * @return 成功-OK
         */
        public static String flushDB() {
            Jedis jedis = getInstance().getResource();
            String data = jedis.flushDB();
            jedis.close();
            return data;
        }

        /**
         * 清空所有数据库的所有数据
         *
         * @return 成功-OK
         */
        public static String flushAll() {
            Jedis jedis = getInstance().getResource();
            String data = jedis.flushAll();
            jedis.close();
            return data;
        }

        /**
         * 选择当前服务器的数据库
         *
         * @param index 【0-15】
         * @return 成功返回OK
         */
        public static String select(int index) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.select(index);
            jedis.close();
            return data;
        }

        /**
         * 查看当前Redis的信息
         *
         * @return 返回数据库相关信息
         */
        public static String info() {
            Jedis jedis = getInstance().getResource();
            String data = jedis.info();
            jedis.close();
            return data;
        }


        /**
         * 查看当前Redis某个模块的信息的信息
         *
         * @param section 模块名称[Server、Clients、Memory、Persistence、Stats、Replication、CPU、Cluster、Keyspace]
         * @return 相关信息
         */
        public static String info(String section) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.info(section);
            jedis.close();
            return data;
        }


        /**
         * 验证连接池是否未单例模式
         */
        public static void test() {
            System.out.println("test is single ....?");
        }
    }

    /**********************************************
     * String(字符串)
     *********************************************/
    public static class JedisStringUtil {
        /**
         * 添加数据,如果key存在，则覆盖原有的数据
         *
         * @param key   键
         * @param value 值
         * @return OK
         */
        public static String set(String key, String value) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.set(key, value);
            jedis.close();
            return data;
        }

        /**
         * 添加数据,如果key存在，则覆盖原有的数据
         *
         * @param key   键的byte[]
         * @param bytes 值的byte[]
         * @return OK
         */
        public static String set(byte[] key, byte[] bytes) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.set(key, bytes);
            jedis.close();
            return data;
        }

        /**
         * 同时设置多个键值对,如果key存在，则覆盖原有的数据
         *
         * @param key_values 键值对
         * @return OK
         */
        public static String mset(String... key_values) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.mset(key_values);
            jedis.close();
            return data;
        }

        /**
         * 同时设置多个键值对,如果key存在，则覆盖原有的数据
         *
         * @param key_values 键值对
         * @return OK
         */
        public static String mset(byte[]... key_values) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.mset(key_values);
            jedis.close();
            return data;
        }

        /**
         * 同时设置多个键值对,如果key存在，则不执行设置操作(要么全部设置成功，要么全部设置失败)
         *
         * @param key_values 键值对
         * @return 所有key都设值成功-1，如果有1个key已存在则是失败-0
         */
        public static long msetnx(byte[]... key_values) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.msetnx(key_values);
            jedis.close();
            return data;
        }

        /**
         * 同时设置多个键值对,如果key存在，则不执行设置操作(要么全部设置成功，要么全部设置失败)
         *
         * @param key_values 键值对
         * @return 所有key都设值成功-1，如果有1个key已存在则是失败-0
         */
        public static long msetnx(String... key_values) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.msetnx(key_values);
            jedis.close();
            return data;
        }

        /**
         * 添加数据，当key不存在时可以设置value,当可以存在是不做任何动作
         *
         * @param key   键
         * @param value 值
         * @return 设置成功-1，设置失败-0
         */
        public static long setnx(String key, String value) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.setnx(key, value);
            jedis.close();
            return data;
        }

        /**
         * 添加数据，当key不存在时可以设置value,当可以存在是不做任何动作
         *
         * @param key   键的byte[]
         * @param value 值的byte[]
         * @return 设置成功-1，设置失败-0
         */
        public static long setnx(byte[] key, byte[] value) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.setnx(key, value);
            jedis.close();
            return data;
        }

        /**
         * 设置值的同时设置key的生存时间(如果key存在，则覆盖旧值)
         *
         * @param key     键
         * @param seconds 键的生存时间，单位：秒
         * @param value   值
         * @return 设置成功返回-OK，失败-错误
         */
        public static String setex(byte[] key, int seconds, byte[] value) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.setex(key, seconds, value);
            jedis.close();
            return data;
        }

        /**
         * 设置值的同时设置key的生存时间(如果key存在，则覆盖旧值)
         *
         * @param key     键
         * @param seconds 键的生存时间，单位：秒
         * @param value   值
         * @return 设置成功返回-OK，失败-错误
         */
        public static String setex(String key, int seconds, String value) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.setex(key, seconds, value);
            jedis.close();
            return data;
        }

        /**
         * 设置key的过期时间，如果key不存在不做任何操作
         *
         * @param key     键
         * @param seconds 过期时间，单位：秒
         * @return 设置成功-1，设置失败-0
         */
        public static long expire(String key, int seconds) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.expire(key, seconds);
            jedis.close();
            return data;
        }

        /**
         * 设置key的过期时间，如果key不存在不做任何操作
         *
         * @param key     键
         * @param seconds 过期时间，单位：秒
         * @return 设置成功-1，设置失败-0
         */
        public static long expire(byte[] key, int seconds) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.expire(key, seconds);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字值增1。如果不存在，会先把value初始化为0，在加1
         *
         * @param key 键
         * @return 执行incr命令后key的值
         */
        public static long incr(byte[] key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.incr(key);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字值增1。如果不存在，会先把value初始化为0，在加1
         *
         * @param key 键
         * @return 执行incr命令后key的值
         */
        public static long incr(String key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.incr(key);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字增加increment。如果不存在，会先把value初始化为0，在加increment
         *
         * @param key       键
         * @param increment 增量
         * @return 加上increment增量后的值
         */
        public static long incrBy(String key, long increment) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.incrBy(key, increment);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字增加increment。如果不存在，会先把value初始化为0，在加increment
         *
         * @param key       键
         * @param increment 增量
         * @return 加上increment增量后的值
         */
        public static long incrBy(byte[] key, long increment) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.incrBy(key, increment);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的浮点数字增加increment。如果不存在，会先把value初始化为0，在加increment
         *
         * @param key       键
         * @param increment 增量
         * @return 加上increment增量后的值
         */
        public static double incrByFloat(byte[] key, double increment) {
            Jedis jedis = getInstance().getResource();
            double data = jedis.incrByFloat(key, increment);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的浮点数字增加increment。如果不存在，会先把value初始化为0，在加increment
         *
         * @param key       键
         * @param increment 增量
         * @return 加上increment增量后的值
         */
        public static double incrByFloat(String key, double increment) {
            Jedis jedis = getInstance().getResource();
            double data = jedis.incrByFloat(key, increment);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字值减1。如果不存在，会先把value初始化为0，在减1
         *
         * @param key 键
         * @return 执行decr命令后key的值
         */
        public static long decr(byte[] key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.decr(key);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字值减1。如果不存在，会先把value初始化为0，在减1
         *
         * @param key 键
         * @return 执行decr命令后key的值
         */
        public static long decr(String key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.decr(key);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字减少decrement。如果不存在，会先把value初始化为0，在减decrement
         *
         * @param key       键
         * @param decrement 减少量
         * @return 减去decrement的值
         */
        public static long decrBy(String key, long decrement) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.decrBy(key, decrement);
            jedis.close();
            return data;
        }

        /**
         * 将key中存储的数字减少decrement。如果不存在，会先把value初始化为0，在减decrement
         *
         * @param key       键
         * @param decrement 减少量
         * @return 减去decrement的值
         */
        public static long decrBy(byte[] key, long decrement) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.decrBy(key, decrement);
            jedis.close();
            return data;
        }

        /**
         * 获取值
         *
         * @param key 键
         * @return 值
         */
        public static String get(String key) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.get(key);
            jedis.close();
            return data;
        }

        /**
         * 获取值(byte[])
         *
         * @param key 键的byte[]
         * @return 值的byte[]
         */
        public static byte[] get(byte[] key) {
            Jedis jedis = getInstance().getResource();
            byte[] bytes = jedis.get(key);
            jedis.close();
            return bytes;
        }

        /**
         * 获取值多个键的值集合
         *
         * @param keys 多个键的byte[]
         * @return 多个键的值的byte[]集合
         */
        public static List<byte[]> mget(byte[]... keys) {
            Jedis jedis = getInstance().getResource();
            List<byte[]> data = jedis.mget(keys);
            jedis.close();
            return data;
        }

        /**
         * 获取值多个键的值集合
         *
         * @param keys 多个键
         * @return 多个键的值的byte[]集合
         */
        public static List<String> mget(String... keys) {
            Jedis jedis = getInstance().getResource();
            List<String> data = jedis.mget(keys);
            jedis.close();
            return data;
        }

        /**
         * 获取字符串中的子字符串，字符串的截取位置范围有startOffset和endOffset两个偏移量决定。
         * 负偏移量表示从字符串最后开始计算，-1表示最后一个字符，-1表示倒数第二个字符，以此类推.
         *
         * @param key         键
         * @param startOffset 开始偏移量，字符串从下标0开始
         * @param endOffset   结束偏移量，包含当前结束下标。超出范围的部分默认忽略
         * @return 截取后的字符串
         */
        public static String getrange(String key, int startOffset, int endOffset) {
            Jedis jedis = getInstance().getResource();
            String data = jedis.getrange(key, startOffset, endOffset);
            jedis.close();
            return data;
        }

        /**
         * 获取字符串中的子字符串，字符串的截取位置范围有startOffset和endOffset两个偏移量决定。
         * 负偏移量表示从字符串最后开始计算，-1表示最后一个字符，-1表示倒数第二个字符，以此类推
         *
         * @param key         键
         * @param startOffset 开始偏移量，字符串从下标0开始
         * @param endOffset   结束偏移量，包含当前结束下标。超出范围的部分默认忽略
         * @return 截取后的字符串
         */
        public static byte[] getrange(byte[] key, int startOffset, int endOffset) {
            Jedis jedis = getInstance().getResource();
            byte[] data = jedis.getrange(key, startOffset, endOffset);
            jedis.close();
            return data;
        }

        /**
         * 删除一个key
         *
         * @param key 键
         * @return 删除成功-1，失败-0
         */
        public static long del(String key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.del(key);
            jedis.close();
            return data;
        }

        /**
         * 删除一个key
         *
         * @param key 键
         * @return 删除成功-1，失败-0
         */
        public static long del(byte[] key) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.del(key);
            jedis.close();
            return data;
        }

        /**
         * 删除多个keys
         *
         * @param keys 多个键
         * @return 删除成功-1，失败-0
         */
        public static long del(String... keys) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.del(keys);
            jedis.close();
            return data;
        }

        /**
         * 删除多个keys
         *
         * @param keys 多个键
         * @return 删除成功-1，失败-0
         */
        public static long del(byte[]... keys) {
            Jedis jedis = getInstance().getResource();
            long data = jedis.del(keys);
            jedis.close();
            return data;
        }

        /**
         * 返回key所存储的字符串的长度
         *
         * @param key 键
         * @return 字符串的长度，当key不存在返回 0
         */
        public static long strlen(String key) {
            Jedis jedis = getInstance().getResource();
            long len = jedis.strlen(key);
            jedis.close();
            return len;
        }
    }

    /**********************************************
     * List(列表)
     *********************************************/
    public static class JedisListUtil{

    }
}
